package com.molichuxing.services.utils;

import com.molichuxing.framework.utils.SnowflakeUtil;
import com.molichuxing.services.contants.OrderStatusConst;
import com.molichuxing.services.infrastructure.bean.OrderScheduleBean;
import com.molichuxing.services.infrastructure.dto.request.create.OrderScheduleUserCreateDto;
import com.molichuxing.services.property.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.List;

/**
 * @Author: renzhengyu
 * @Description:
 * @Date: Created in 10:08 2019/8/28
 * @Modified By:
 **/
public class OrderUtil {
    private static final Logger logger = LoggerFactory.getLogger(OrderUtil.class);

    public static Long getOrderCode() {
        return Long.valueOf(SnowflakeUtil.getId());
    }

    /**
     * 订阅里程状态名称转换
     *
     * @param orderStatus 订阅里程状态枚举
     * @param isRenew     是否续订
     * @return
     */
    public static String transSubscribeFlowStatusName(OrderSubscribeStatusEnum orderStatus, boolean isRenew) {
        String name = "";
        switch (orderStatus) {
            case TRADE_UNPAID:
                // 待付款
                name = "提交订单";
                break;
            case TRADE_CANCELED:
                // 已取消
                name = "订单已取消";
                break;
            case TRADE_UNAUDIT:
                // 待审核
                name = "已支付";
                break;
            case TRADE_UNDELIVERY:
                // 待提车
                name = "审核通过";
                break;
            case TRADE_USE:
                // 用车中
                if (isRenew) {
                    name = "原单已到期";
                } else {
                    name = "已提车";
                }
                break;
            case TRADE_UNUSE:
                // 待用车
                name = "已支付";
                break;
            case TRADE_REJECTED:
                // 审核驳回
                name = "审核驳回";
                break;
            case TRADE_REFUND:
                // 退款中
                name = "发起退款";
                break;
            case TRADE_FINISH:
                // 交易结束
                name = "退款已完成";
                break;
            case RETURN_UNINSPECTED:
                // 待验车
                name = "已还车";
                break;
            case RETURN_UNCONFIRM:
                // 报告待确认
                name = "验车已完成";
                break;
            case RETURN_INTERVENE:
                // 待人工介入
                name = "报告已确认";
                break;
            case RETURN_UNPAID:
                // 待缴费
                name = "报告已确认";
                break;
            case RETURN_FINISH:
                // 已完成
                name = "已缴费";
                break;
            default:
                break;
        }
        return name;
    }

    /**
     * 专属里程状态名称转换
     *
     * @param orderStatus   专属里程状态枚举
     * @param paymentMethod 付款类型
     * @return
     */
    public static String transExclusivelFlowStatusName(OrderExclusivelStatusEnum orderStatus,
                                                       OrderPaymentMethodEnum paymentMethod) {
        String name = "";
        switch (orderStatus) {
            case TRADE_UNPAID:
                // 待付款
                name = "提交订单";
                break;
            case TRADE_CANCELED:
                // 已取消
                name = "已取消";
                break;
            case TRADE_UNAUDIT:
                // 待审核
                name = "已支付首付款";
                break;
            case TRADE_UNDELIVERY:
                // 待提车
                switch (paymentMethod) {
                    case FULL:
                        name = "已支付";
                        break;
                    case INSTALLMENT:
                        name = "审核通过";
                        break;
                }
                break;
            case TRADE_USE:
                // 用车中
                name = "已提车";
                break;
            case TRADE_REJECTED:
                // 审核驳回
                name = "审核驳回";
                break;
            case TRADE_REFUND:
                // 退款中
                name = "发起退款";
                break;
            case TRADE_FINISH:
                name = "退款已完成";
                break;
            default:
                break;
        }
        return name;
    }

    public static List<Integer> getStatusList(OrderTypeEnum orderType, OrderListTypeEnum orderListType) {
        List<Integer> result = new ArrayList<>();
        if (OrderTypeEnum.EXCLUSIVEL.equals(orderType) && OrderListTypeEnum.TRADE_LIST.equals(orderListType)) {
            // 专属订单交易列表
            for (OrderExclusivelStatusEnum orderExclusivelStatus : OrderStatusConst.TRADE_EXCLUSIVEL_STATUS) {
                result.add(orderExclusivelStatus.getValue());
            }
        } else if (OrderTypeEnum.EXCLUSIVEL.equals(orderType) && OrderListTypeEnum.CREDIT_LIST.equals(orderListType)) {
            // 专属订单征信审核
            for (OrderExclusivelStatusEnum orderExclusivelStatus : OrderStatusConst.CREDIT_EXCLUSIVEL_STATUS) {
                result.add(orderExclusivelStatus.getValue());
            }
        } else if (OrderTypeEnum.EXCLUSIVEL.equals(orderType) && OrderListTypeEnum.RENEGE_LIST.equals(orderListType)) {
            // 专属订单提前退租
            for (OrderExclusivelStatusEnum orderExclusivelStatus : OrderStatusConst.RENEGE_EXCLUSIVEL_STATUS) {
                result.add(orderExclusivelStatus.getValue());
            }
        } else if (OrderTypeEnum.SUBSCRIBE.equals(orderType) && OrderListTypeEnum.TRADE_LIST.equals(orderListType)) {
            // 订阅订单交易列表
            for (OrderSubscribeStatusEnum orderSubscribeStatus : OrderStatusConst.TRADE_SUBSCRIBE_STATUS) {
                result.add(orderSubscribeStatus.getValue());
            }
        } else if (OrderTypeEnum.SUBSCRIBE.equals(orderType) && OrderListTypeEnum.CREDIT_LIST.equals(orderListType)) {
            // 订阅订单征信审核
            for (OrderSubscribeStatusEnum orderSubscribeStatus : OrderStatusConst.CREDIT_SUBSCRIBE_STATUS) {
                result.add(orderSubscribeStatus.getValue());
            }
        } else if (OrderTypeEnum.SUBSCRIBE.equals(orderType) && OrderListTypeEnum.RETURN_LIST.equals(orderListType)) {
            // 订阅订单到期还车
            for (OrderSubscribeStatusEnum orderSubscribeStatus : OrderStatusConst.RETURN_SUBSCRIBE_STATUS) {
                result.add(orderSubscribeStatus.getValue());
            }
        }
        return result;
    }

    /**
     * 获取正常订单状态（订阅订单、专属订单）
     *
     * @param orderType 订单类型
     * @return
     */
    public static List<Integer> getNormalStatus(OrderTypeEnum orderType) {
        List<Integer> result = new ArrayList<>();
        switch (orderType) {
            case EXCLUSIVEL:
                // 专属
                for (OrderExclusivelStatusEnum orderStatus : OrderExclusivelStatusEnum.values()) {
                    if (!OrderExclusivelStatusEnum.TRADE_CANCELED.equals(orderStatus)) {
                        result.add(orderStatus.getValue());
                    }
                }
                break;
            case SUBSCRIBE:
                // 订阅
                for (OrderSubscribeStatusEnum orderStatus : OrderSubscribeStatusEnum.values()) {
                    if (!OrderSubscribeStatusEnum.TRADE_CANCELED.equals(orderStatus)) {
                        result.add(orderStatus.getValue());
                    }
                }
                break;
            default:
                break;
        }

        return result;
    }

    /**
     * 生成排期信息
     *
     * @param createDto
     * @return
     */
    public static List<OrderScheduleBean> generateOrderSchedule(OrderScheduleUserCreateDto createDto) {
        List<OrderScheduleBean> result = null;

        if (OrderPaymentMethodEnum.FULL.equals(createDto.getPaymentMethod())) {
            // 全款
            result = generateOrderScheduleByFull(createDto);
        } else if (OrderPaymentMethodEnum.INSTALLMENT.equals(createDto.getPaymentMethod())) {
            // 分期
            result = generateOrderScheduleByInstallment(createDto);
        }

        return result;
    }

    /**
     * 生成全款排期信息
     *
     * @param createDto
     * @return
     */
    public static List<OrderScheduleBean> generateOrderScheduleByFull(OrderScheduleUserCreateDto createDto) {
        List<OrderScheduleBean> result = new ArrayList<>(createDto.getTotalPeriods());
        BigDecimal payable = createDto.getRental().divide(new BigDecimal(createDto.getTotalPeriods()), 0,
                RoundingMode.HALF_DOWN);
        BigDecimal tmpPayable = BigDecimal.ZERO;
        for (int periods = 1; periods <= createDto.getTotalPeriods(); periods++) {
            OrderScheduleBean orderScheduleBean = new OrderScheduleBean();
            orderScheduleBean.setOrderCode(createDto.getOrderCode());
            orderScheduleBean.setPeriods(periods);
            orderScheduleBean.setTotalPeriods(createDto.getTotalPeriods());
            // 应付款金额（最后一期为总金额减去前面所有期数金额）
            orderScheduleBean.setPayable(
                    periods == createDto.getTotalPeriods() ? createDto.getRental().subtract(tmpPayable) : payable);
            orderScheduleBean.setPayableDate(createDto.getPaySuccessTime().toLocalDate());
            orderScheduleBean.setDeposit(periods == 1 ? createDto.getDeposit() : BigDecimal.ZERO);
            orderScheduleBean.setUserId(createDto.getUserId());
            orderScheduleBean.setPaySuccessTime(createDto.getPaySuccessTime());
            orderScheduleBean.setPayWay(createDto.getPayWay().getValue());
            orderScheduleBean.setRepayTerminal(createDto.getRepayTerminal());
            orderScheduleBean.setStatus(OrderScheduleStatusEnum.ALREADY.getValue());

            tmpPayable = tmpPayable.add(payable);

            result.add(orderScheduleBean);
        }
        return result;
    }

    /**
     * 生成分期排期信息
     *
     * @param createDto
     * @return
     */
    public static List<OrderScheduleBean> generateOrderScheduleByInstallment(OrderScheduleUserCreateDto createDto) {
        List<OrderScheduleBean> result = new ArrayList<>(createDto.getTotalPeriods());
        BigDecimal tmpPayable = BigDecimal.ZERO;
        LocalDate payableDate = createDto.getPaySuccessTime().toLocalDate();
        for (int periods = 1; periods <= createDto.getTotalPeriods(); periods++) {
            OrderScheduleBean orderScheduleBean = new OrderScheduleBean();
            orderScheduleBean.setOrderCode(createDto.getOrderCode());
            orderScheduleBean.setPeriods(periods);
            orderScheduleBean.setTotalPeriods(createDto.getTotalPeriods());
            orderScheduleBean.setPayable(createDto.getRental());
            orderScheduleBean.setPayableDate(payableDate);
            orderScheduleBean.setDeposit(periods == 1 ? createDto.getDeposit() : BigDecimal.ZERO);
            orderScheduleBean.setUserId(createDto.getUserId());
            if (periods == 1) {
                // 第一期
                orderScheduleBean.setPaySuccessTime(createDto.getPaySuccessTime());
                orderScheduleBean.setPayWay(createDto.getPayWay().getValue());
                orderScheduleBean.setRepayTerminal(createDto.getRepayTerminal());
                orderScheduleBean.setStatus(OrderScheduleStatusEnum.ALREADY.getValue());
            } else if (periods == createDto.getTotalPeriods()) {
                // 最后一期
                orderScheduleBean.setPayable(createDto.getCartFee().subtract(tmpPayable));
                orderScheduleBean.setStatus(OrderScheduleStatusEnum.NO.getValue());
            } else {
                orderScheduleBean.setStatus(OrderScheduleStatusEnum.NO.getValue());
            }
            // 判断当前支付日期是否是每月的29、30、31号
            int day = payableDate.getDayOfMonth();
            if (day == 29 || day == 30 || day == 31) {
                // 是，转换成28号
                payableDate = LocalDate.of(payableDate.getYear(), payableDate.getMonthValue(), 28);
            }
            payableDate = payableDate.plus(createDto.getRepaymentPeriod(), ChronoUnit.MONTHS);

            tmpPayable = tmpPayable.add(createDto.getRental());

            result.add(orderScheduleBean);
        }

        return result;
    }
}
